package com.mojito.learn.design.patterns;

/**
 * 桥接模式
 * <p>
 * 使用桥接模式通过将实现和抽象放在两个不同的类层次中而使它们可以独立改变。
 *
 * @author liufq
 * @since 2022/1/25 下午5:27
 */
public class BridgePattern {

    public static void main(String[] args) {
        RemoteControl remoteControl1 = new ConcreteRemoteControl1(new RCA());
        remoteControl1.on();
        remoteControl1.off();
        remoteControl1.tuneChannel();
    }

    public static abstract class TV {
        public abstract void on();

        public abstract void off();

        public abstract void tuneChannel();
    }

    public class Sony extends TV {
        @Override
        public void on() {
            System.out.println("Sony.on()");
        }

        @Override
        public void off() {
            System.out.println("Sony.off()");
        }

        @Override
        public void tuneChannel() {
            System.out.println("Sony.tuneChannel()");
        }
    }

    public static class RCA extends TV {
        @Override
        public void on() {
            System.out.println("RCA.on()");
        }

        @Override
        public void off() {
            System.out.println("RCA.off()");
        }

        @Override
        public void tuneChannel() {
            System.out.println("RCA.tuneChannel()");
        }
    }

    public static abstract class RemoteControl {
        protected TV tv;

        public RemoteControl(TV tv) {
            this.tv = tv;
        }

        public abstract void on();

        public abstract void off();

        public abstract void tuneChannel();
    }

    public static class ConcreteRemoteControl1 extends RemoteControl {
        public ConcreteRemoteControl1(TV tv) {
            super(tv);
        }

        @Override
        public void on() {
            System.out.println("ConcreteRemoteControl1.on()");
            tv.on();
        }

        @Override
        public void off() {
            System.out.println("ConcreteRemoteControl1.off()");
            tv.off();
        }

        @Override
        public void tuneChannel() {
            System.out.println("ConcreteRemoteControl1.tuneChannel()");
            tv.tuneChannel();
        }
    }

    public class ConcreteRemoteControl2 extends RemoteControl {
        public ConcreteRemoteControl2(TV tv) {
            super(tv);
        }

        @Override
        public void on() {
            System.out.println("ConcreteRemoteControl2.on()");
            tv.on();
        }

        @Override
        public void off() {
            System.out.println("ConcreteRemoteControl2.off()");
            tv.off();
        }

        @Override
        public void tuneChannel() {
            System.out.println("ConcreteRemoteControl2.tuneChannel()");
            tv.tuneChannel();
        }
    }
}
